<?php
namespace app\comm\lib;

use think\Model;

class BaseModel extends Model
{
    use \think\model\concern\SoftDelete;
    protected $deleteTime = 'delete_time';
    public $listAllowField = [];
    public $listExceptField = [];

    // 删除前校验，格式如下：后面三项选填
    protected $_deleteValidate = [
        //['关联表名'，'关联表字段名（外键）'，'文字提示',['附加条件，请用thinkphp数组条件模式'],'本表关联字段名，默认为主键id']
    ];
    // 通过
    /**
     * 删除 并校验
     * @param $data
     * @param bool $force
     * @return bool
     */
    public function deleteData($data, $force = false){
        if (!empty($this->_deleteValidate) && $this->deleteValidateList($data) === false){
            return false;
        }
        return $this->destroy($data, $force);
    }
    /**
     * 校验删除数据
     * @param $key
     * @return bool
     */
    public function deleteValidateList($key){
        if (empty($this->_deleteValidate)){
            return true;
        }
        foreach ($this->_deleteValidate as $item){
            $table = $item[0];
            $field = $item[1];
            array_key_exists(2, $item)? $message = $item[2]: $message = '存在关联数据，不能删除!';
            array_key_exists(3, $item)? $where = $item[3]: $where = [];
            array_key_exists(4, $item)? $relevanceKey = $item[4]: $relevanceKey = 'id';
            if ($this->deleteValidateOne($key, $table, $field, $where, $relevanceKey) === false){
                $this->error = $message;
                return false;
            }
        }
        return true;
    }

    /**
     * 判断当前id与$table表关联的值的是否存在，存在则返回false
     * @param $key
     * @param $field
     * @param $table
     * @param $where
     * @param $relevanceKey
     * @return bool
     */
    public function deleteValidateOne($key, $table,  $field,$where, $relevanceKey){
        $column = $this->where([['id', 'in', $key]])->column($relevanceKey);
        if(empty($column)){
            return true;
        }
        $where[] = [$field, 'in', $column];
        if (model($table)->where($where)->find()){
            return false;
        } else {
            return true;
        }
    }
    /**
     * 获取count统计值
     * @param array $where 采用数组查询
     * @return float|string
     */
    public function getListForCount($where = []){
        return $this->where($where)->count();
    }

    /**
     * 分页获取数据  采用数组查询
     * @param array $where
     * @param int $page
     * @param int $page_nums
     * @param string $order
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getListForPage($where=[], $page=1, $page_nums=20, $order = ''){
        if($order != ''){
            $data_list = $this->field($this->listExceptField, true)->where($where)->order($order)->page($page, $page_nums)->select();
        } else {
            $data_list = $this->field($this->listExceptField, true)->where($where)->page($page, $page_nums)->select();
        }
        if (empty($data_list) || $data_list->isEmpty()){
            return $data_list;
        }
        if (method_exists($this, 'setAddedField')){
            foreach ($data_list as &$item){
                $this->setAddedField($item);
            }
        }
        return $data_list;
    }

    // $item['cate_desc'] = model('BusinessCate')->where('id', $item['cate_id'])->value('title');
    public function getAddedFieldValue($table, $key, $value, $field){
        if (is_null($value)){
            return null;
        }
        return model($table)->where($key, $value)->value($field);
    }

    /**
     * 获取一条数据
     * @param $id
     * @return array|Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getOne($id)
    {
        if(is_array($id)){
            $data = $this->where($id)->find();
        }else{
            $data = $this->find($id);
        }
        if(empty($data)){
            return [];
        }
        if (method_exists($this, 'setAddedField')){
            $this->setAddedField($data);
        }
        return $data;
    }

    /**
     * 通过过滤不存在的字段值，新增
     * @param array $data
     * @param null $field
     * @param bool $replace
     * @return BaseModel|bool
     */
    public function createAdd($data = [], $field = null, $replace = false){
        try{
            return $this->create($data, $field, $replace);
        } catch (\Exception $e){
           $this->error = $e->getMessage();
           return false;
        }

    }

    /**
     * 更新
     * @param array $data
     * @param array $where
     * @param null $field
     * @return BaseModel|bool
     */
    public function updateSave($data = [], $where = [], $field = null){
        try{
            return $this->update($data, $where, $field);
        } catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }

    }

    /**
     * 获取一条随机数据
     * @param $where
     * @return mixed|null
     */
    public function randomOneData($where=[]){
        $arr = $this->where($where)->column('id');
        if(empty($arr)){
            return null;
        }
        $id = $arr[array_rand($arr)];
        $data = $this->get($id);
        if (empty($data) || $data->isEmpty()){
            return null;
        }
        return $data;
    }

    /**
     * 获取随机列表
     * @param int $num
     * @param array $where
     * @param null $order
     * @param string $field
     * @return array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function randomListData($num = 10, $where=[], $order=null, $field='id'){
        $arr = $this->where($where)->column($field);
        if(empty($arr)){
            return [];
        }
        $keys = array_rand($arr,$num);
        $ids = [];
        foreach($keys as $item){
            $ids[] = $arr[$item];
        }
        if (empty($ids)){
            return [];
        }
        return $this->where($field, 'in', $ids)->order($order)->select();
    }
}